package vn.conghuy.talkwithme.data.wolfram;

import java.util.ArrayList;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import vn.conghuy.talkwithme.utils.Utils;


public class WolframService {
	
	static String POD = "pod";
	static String SUBPOD = "subpod";
	static String PLAINTEXT = "plaintext";
	static String IMG = "img";
	static String TITLE = "title";
	static String ASSUMPTIONS = "assumptions";
	static String ASSUMPTION = "assumption";
	static String VALUE = "value";
	static String NAME = "name";
	static String DESC = "desc";
	static String INPUT = "input";
	static String SUCCESS = "success";
	
	ArrayList<WolframPod> pods;
	ArrayList<WolframAssumtion> assumptions;
	String request;
	String apiKey;
	boolean isSuccess;
	int curPod;				//current pod is using for nextPod() function
	String xml;
	
	public WolframService(String apiKey) {
		pods = new ArrayList<WolframPod>();
		assumptions = new ArrayList<WolframAssumtion>();
		this.apiKey = apiKey;
	}
	
	public boolean request(String request){
		
		//format white space in request to html format
		String[] words = request.split(" ");
		request = "";
		for(String word : words){
			request += word+"%20";
		}
		request = request.substring(0, request.length() - 3);
		
		this.request = request;
		pods.clear();
		assumptions.clear();
		
		xml = Utils.requestHtmlContent("http://api.wolframalpha.com/v2/query?input=" + request +"&appid=" + apiKey);
		if(xml == null) return false;
		
		//Read xml.
		Document dom = Utils.stringToDom(xml);
		
		Element rootElem = dom.getDocumentElement();
		if(rootElem.getAttribute(SUCCESS).equals("false")) {
			return false;
		}
		
		NodeList nlPods = rootElem.getElementsByTagName(POD);
		
		// foreach pod
		for(int i = 0; i < nlPods.getLength(); i++){
			WolframPod pod = new WolframPod();
			
			//get title
			Element ePod = (Element)nlPods.item(i);
			pod.setTitle(ePod.getAttribute(TITLE));
			
			NodeList nlSubPod = ePod.getElementsByTagName(SUBPOD);
			Element eSubPod = (Element)nlSubPod.item(0);
			
			//get plaintext
			NodeList nlPlainText = eSubPod.getElementsByTagName(PLAINTEXT);
			Element ePlainText = (Element)nlPlainText.item(0);
			pod.setPlainText(ePlainText.getTextContent());
			
			//get image
			NodeList nlImage = eSubPod.getElementsByTagName(IMG);
			Element eImage = (Element)nlImage.item(0);
			pod.setImage("<img src=" + eImage.getAttribute("src") + "></img>");
			
			pods.add(pod);
		}
		
		NodeList nlAssumptions = rootElem.getElementsByTagName(ASSUMPTIONS);
		if(nlAssumptions.getLength() > 0){
			Element eAssumptions = (Element)nlAssumptions.item(0);
			
			NodeList nlAssumption = eAssumptions.getElementsByTagName(ASSUMPTION);
			Element eAssumption = (Element)nlAssumption.item(0);
			
			NodeList nlValue = eAssumption.getElementsByTagName(VALUE);
			
			for(int i = 0; i < nlValue.getLength(); i++){
				WolframAssumtion assumption = new WolframAssumtion();
				Element eValue = (Element)nlValue.item(i);
				
				String name = eValue.getAttribute(NAME);
				assumption.setName(name);
				
				String desc = eValue.getAttribute(DESC);
				assumption.setDesc(desc);
				
				String input = eValue.getAttribute(INPUT);
				assumption.setInput(input);
				
				assumptions.add(assumption);
			}
		}
		
		return true;
	}
	
	public WolframPod getFirstResult(){
		if(pods.size() >= 1){
			curPod = 1;
			return pods.get(1);
		}
		else return null;
	}
	
	public WolframPod nextPod(){
		curPod++;
		if(curPod < pods.size())
			return pods.get(curPod);
		else return null;
	}

	public ArrayList<WolframPod> getPods() {
		return pods;
	}
	
	public WolframPod getPod(String request) {
		for(WolframPod pod:pods){
			if(request.toLowerCase().contains(pod.getTitle().toLowerCase())){
				return pod;
			}
		}
		return null;
	}
	
	public WolframAssumtion getAssumption(String request) {
		for(WolframAssumtion assumption:assumptions){
			if(request.toLowerCase().contains(assumption.getDesc().toLowerCase())){
				return assumption;
			}
		}
		return null;
	}

	public ArrayList<WolframAssumtion> getassumptions() {
		return assumptions;
	}

	/**
	 * @return
	 * @uml.property  name="request"
	 */
	public String getRequest() {
		return request;
	}

	/**
	 * @param apiKey
	 * @uml.property  name="apiKey"
	 */
	public void setApiKey(String apiKey) {
		this.apiKey = apiKey;
	}

	/**
	 * @return
	 * @uml.property  name="isSuccess"
	 */
	public boolean isSuccess() {
		return isSuccess;
	}
}
